import json

from django.http import JsonResponse
from django.views import View
from django.contrib.auth import login, logout

from apps.users.utils import generic_email_verify_token, check_email_verify_token
from utils.views import LoginRequiredJSONMixin
from celery_tasks.email.tasks import celery_send_email

from apps.users.models import User
import re


# Create your views here.
# 判断用户名是否重复
# 请求:接收参数:username
# 业务逻辑: 根据用户名查询数据库,如果count大于0,说明用户名重复,否则用户名可用
# 响应: 返回json数据: {"code":200,"count":0/1,"errmsg":"ok"}
# 路由 GET usernames/<username>/count/
class UsernameCountView(View):
    def get(self, request, username):
        # 通过转换器对用户名进行检查,a-z,A-Z,0-9,_,需要在5~20个字符之间
        count = User.objects.filter(username=username).count()
        return JsonResponse({'code': 200, 'count': count, 'errmsg': 'ok'})


class MobileCountView(View):
    """判断手机号是否重复注册"""

    def get(self, request, mobile):
        """
        :param request: 请求对象
        :param mobile: 手机号
        :return: JSON
        """
        count = User.objects.filter(mobile=mobile).count()
        return JsonResponse({'code': 0, 'errmsg': 'OK', 'count': count})


# 注册
# 请求:接收参数:username,password,password2,mobile,allow
# 业务逻辑: 验证数据,数据入库
# 响应: 返回json数据: {"code":200,"errmsg":"ok"}
# 路由 POST register/
class RegisterView(View):
    def post(self, request):
        # 1.接收参数
        body_bytes = request.body
        body_str = body_bytes.decode()
        print(body_str)
        body_dict = json.loads(body_str)
        # 2.获取数据
        username = body_dict.get('username')
        password = body_dict.get('password')
        password2 = body_dict.get('password2')
        mobile = body_dict.get('mobile')
        # sms_code = body_dict.get('sms_code')
        allow = body_dict.get('allow')
        # 3.验证数据
        #   3.1 判断参数是否齐全
        if not all([username, password, password2, mobile, allow]):
            return JsonResponse({'code': 400, 'errmsg': '缺少必传参数'})
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return JsonResponse({'code': 400, 'errmsg': '用户名格式不正确'})
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return JsonResponse({'code': 400, 'errmsg': '密码格式不正确'})
        if password != password2:
            return JsonResponse({'code': 400, 'errmsg': '两次密码不一致'})
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400, 'errmsg': '手机号格式不正确'})
        # if not re.match(r'^[0-9a-zA-Z]{4}$', sms_code):
        #     return JsonResponse({'code': 400, 'errmsg': '短信验证码格式不正确'})
        if not allow:
            return JsonResponse({'code': 400, 'errmsg': '请勾选用户协议'})

        try:
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
            user.save()
            login(request, user)
            return JsonResponse({'code': 200, 'errmsg': 'ok'})
        except Exception as e:
            print(f"Exception occurred: {str(e)}")
            # Exception occurred: Error 10061 connecting to 127.0.0.1:6379. 由于目标计算机积极拒绝，无法连接。.
            return JsonResponse({'code': 400, 'errmsg': '注册失败!!!'})


# 登录
# 请求:接收参数:username,password,验证参数
# 业务逻辑: 验证数据,数据入库
# 响应: 返回json数据: {"code":200,"errmsg":"ok"}
# 路由 POST login/
class LoginView(View):
    def post(self, request):
        # 1.接收数据
        json_data = json.loads(request.body.decode())
        username = json_data.get('username')
        password = json_data.get('password')
        remembered = json_data.get('remembered')
        # 2.验证数据
        if not all([username, password]):
            return JsonResponse({'code': 400, 'errmsg': '缺少必传参数'})
        # 2.1 判断是根据手机号登录还是用户名登录
        if re.match(r'^1[3-9]\d{9}$', username):
            # 手机号登录
            User.USERNAME_FIELD = 'mobile'
        else:
            User.USERNAME_FIELD = 'username'
        # 3.验证用户密码是否正确
        from django.contrib.auth import authenticate
        user = authenticate(username=username, password=password)
        if user is None:
            return JsonResponse({'code': 400, 'errmsg': '用户名或密码错误'})
        # 4.session
        login(request, user)
        # 5.判断是否记住用户
        if remembered:
            request.session.set_expiry(None)
        else:
            request.session.set_expiry(0)
        # 6.响应结果
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})
        response.set_cookie('username', user.username, max_age=14 * 24 * 3600)
        return response


# 退出登录
# 请求:接收参数:
# 业务逻辑: 验证数据,数据入库
# 响应: 返回json数据: {"code":200,"errmsg":"ok"}
# 路由 DELETE logout/
class LogoutView(View):
    def delete(self, request):
        # 1.删除session信息
        logout(request)
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})
        # 2. 清除cookie中的username
        response.delete_cookie('username')
        return response


# 个人中心,必须是登录用户才能访问
# 请求:接收参数:
# 业务逻辑: 验证数据,数据入库
# 响应: 返回json数据: {"code":200,"errmsg":"ok"}
# 路由 GET center/
# LoginRequiredMixin:会返回重定向,并不是json数据,我们需要让他不重定向
class CenterView(LoginRequiredJSONMixin, View):
    def get(self, request):
        info_data = {
            'username': request.user.username,
            'email': request.user.email,
            'mobile': request.user.mobile,
            'email_active': request.user.email_active
        }
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'info_data': info_data})


# 保存邮箱地址,发送一封激活邮件,用户激活邮件
# 请求: 接收参数: email
# 业务逻辑: 保存邮箱,发送激活邮件
# 响应 : 返回json数据: {"code":0,"errmsg":"ok"} PUT
class EmailView(View):
    def put(self, request):
        json_data = json.loads(request.body.decode())
        email = json_data.get('email')
        user = request.user
        user.email = email
        user.save()
        # 发送邮件
        subject = '美多商城激活邮件'
        message = ""
        from_email = '美多商城<qi_rui_hua@163.com>'
        recipient_list = ['1065012733@qq.com']
        token = generic_email_verify_token(request.user.id)
        verify_url = "http://www.meiduo.site:8080/success)verify_email.html?token=%s" % token
        html_message = '<p>尊敬的用户您好！</p>' \
                       '<p>感谢您使用美多商城。</p>' \
                       '<p>您的邮箱为：%s 。请点击此链接激活您的邮箱：</p>' \
                       '<p><a href="%s">%s<a></p>' % (email, verify_url, verify_url)
        celery_send_email.delay(
            subject=subject,
            message=message,
            from_email=from_email,
            recipient_list=recipient_list,
            html_message=html_message
        )
        return JsonResponse({'code': 0, 'errmsg': 'ok'})


# 激活用户邮件
# 请求: 接收请求,获取参数,验证参数
# 业务逻辑: user_id,根据用户的id查询数据,修改数据
# 响应 : 返回json数据: {"code":0,"errmsg":"ok"}
# 路由 PUT email/verification/ token不在body里
class EmailVerifyView(View):
    def put(self, request):
        params = request.GET
        token = params.get('token')
        if token is None:
            return JsonResponse({'code': 400, 'errmsg': '缺少参数'})
        user_id = check_email_verify_token(token)
        if user_id is None:
            return JsonResponse({'code': 400, 'errmsg': '无效的token'})
        user = User.objects.get(id=user_id)
        user.email_active = True
        user.save()
        return JsonResponse({'code': 0, 'errmsg': 'ok'})


"""
请求
业务逻辑（数据库的增删改查）
响应


增 （注册）
    1.接收数据
    2.验证数据
    3.数据入库
    4.返回响应

删 
    1.查询到指定记录
    2.删除数据（物理删除，逻辑删除）
    3.返回响应

改  （个人的邮箱）
    1.查询指定的记录
    2.接收数据
    3.验证数据
    4.数据更新
    5.返回响应

查   （个人中心的数据展示，省市区）
    1.查询指定数据
    2.将对象数据转换为字典数据
    3.返回响应
"""
